<?php

namespace app\astrologer\controller\v5;

use app\astrologer\controller\Common;
use app\astrologer\controller\User;
use app\common\cachemodel\AppConfig;
use app\common\cachemodel\zlcr3\Zlcr3ConsultAccount;
use app\common\cachemodel\ZlcrAstr;
use app\common\lib\Alidayu;
use app\common\lib\exception\ApiException;
use app\common\lib\IAuth;
use think\Cache;
use think\Log;

class Login extends Common
{
    /**
     * 手机号登录
     */
    public function telLogin()
    {
        $tel = trim(input('tel/s', ''));
        $code = trim(input('code/s', ''));
        $headers = $this->request->header();
        if (isset($headers['app-type']) && in_array($headers['app-type'], ['ios', 'android'], true))
        {
            $tel = $this->decryptWithOpenssl($tel);
        }
        // 手机号是否存在
        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel))
        {
            Log::write('手机号错误：' . $tel, 'error', true);
            throw new ApiException('手机号错误', 200, 0);
        }

        // 短信验证码 或 密码是否存在
        if (empty($code))
        {
            return show(config('code.error'), '请输入验证码');
        }
        if (mb_strlen($code) !== 6)
        {
            return show(config('code.error'), '验证码错误');
        }
        //防止暴力破解：手机号验证码登录失败10次后 除非重新获取验证码 否则验证码登录 验证码有效期（10分钟）内都自动错误
        $key_of_tel_code_login_error_num = 'login_error_zhunle_astrologer:' . $tel;
        if (Cache::get($key_of_tel_code_login_error_num, 0) >= 10)
        {
            Log::write($tel . '占星师后台手机号验证码登录失败超过10次，验证码失效', 'error');
            return show(config('code.error'), '短信验证码错误！');
        }

        $appConfig = config('app');
        // 短信登录时，检测验证码是否正确
        if (!in_array($tel, $appConfig['mobile'], false) || (strpos($appConfig['code'] * (substr($tel, 3, 6)), $code) !== 0))
        {
            if (($tel == '13045794520' && $code == '666666'))
            {   // 苹果审核 账户
            } else
            {
//              validate 严格校验
                $mobileCode = Alidayu::getInstance()->checkSmsIdentify1($tel, 86, 'astrologer'); // 获取验证码
                if ($code != $mobileCode)
                {// 如果验证码错误
                    Cache::inc($key_of_tel_code_login_error_num);
                    return show(config('code.error'), '短信验证码错误！');
                }
            }
        }

        $astrModel = (new ZlcrAstr());
        $astrInfo = $astrModel->where(['tel' => $tel])->field('id,tel,password,salt,check_status,status,create_time,password_reset_at,token,token_expire')->find();

        if ($astrInfo)
        {
            //状态 1=>正常 0=>禁止（禁止登陆） 2=>账号冻结（可以登录，但是不能接单
            if ((int)$astrInfo['status'] === 0)
            {
                Log::write($tel . '占星师后台手机号登录成功：该用户禁止登陆，请联系客服反馈问题～', 'error');
                return show(config('code.error'), '该用户禁止登陆，请联系客服反馈问题～');
            }
            $simulation_astrologer = config('simulation_astrologer');
            try
            {
                if (in_array($tel, $appConfig['mobile'], false) || ((isset($simulation_astrologer['is_support_muti']) && 1 === (int)$simulation_astrologer['is_support_muti']) && $astrInfo['token_expire'] > $this->request->time()))
                {//是支持多平台 的话 并且access_token没过期，取出模拟的手机号的token
                    $token = $astrInfo['token'];
                    // 更新token到期时间
                    $astrModel->UpdateData($astrInfo['id'], ['id' => $astrInfo['id']], [
                        'token_expire' => strtotime('+' . config('astradmin.login_time_out_day') . ' day')
                    ]);
                } else
                {
                    // 生成token  和 token到期时间
                    $token = IAuth::setAppLoginToken($tel);

                    $data = [
                        'token' => $token,
                        'token_expire' => strtotime('+' . config('astradmin.login_time_out_day') . ' day')
                    ];

                    $astrModel->save($data, ['id' => $astrInfo['id']]);
                }
            }
            catch (\Exception $e)
            {
                Log::write($tel . '占星师后台手机号验证码登录失败：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
                return show(config('code.error'), '登录失败，请稍后再试～');
            }

            $roles = ['astrologer_not_completed'];//未完成章程学习的角色

            if ($this->request->header('version', 1.0) >= 1.2)
            {
                $path = '/quiz/index';//跳转的路径，默认跳转问答
            } else
            {
                $path = '/dashboard/index';//跳转的路径，默认跳转首页
            }

            $is_show_password_reset_msg = false;//在占星师前端是否强制展示修改密码的消息
            if ($astrInfo['check_status'] == 40)
            {
                $roles = ['astrologer'];//完成章程学习的角色/特邀用户
            } else
            {
                $path = '/account/index';//跳转到考试页面
            }
            $consultAccountInfo = (new Zlcr3ConsultAccount())->getInfoById($astrInfo['id']);
            $isConsult = $consultAccountInfo && $consultAccountInfo['consult_status'] === 1 ? 1 : 0;
            $data = [
                'token' => $this->encryptWithOpenssl($token . '||' . $astrInfo['id']),
                'roles' => $roles,
                'path' => $path,
                'step' => User::$statusInfo[$astrInfo['check_status']],
                'is_consult' => $isConsult
            ];
            //状态 1=>正常 0=>禁止（禁止登陆） 2=>账号冻结（可以登录，但是不能接单
            if ($astrInfo['status'] === 2)
            {
                Log::write($tel . '占星师后台手机号登录成功：您的账号已被冻结，请联系客服反馈问题～', 'error');
                return show(406, '您的账号已被冻结，请联系客服反馈问题～', $data);//403: 在其他客户端登录; 405 未登录，前往登录；406：前端提示错误信息，但是返回的数据正常
            } else if ($is_show_password_reset_msg)
            {
                Log::write($tel . '占星师后台手机号登录成功：您已经超过80天未修改密码，为了保障您账号的安全，请尽快修改密码！', 'error');
                return show(406, '您已经超过80天未修改密码，为了保障您账号的安全，请尽快修改密码！', $data);
            } else
            {
                return show(config('code.success'), '登录成功', $data);
            }

        } else
        {
            // 生成token  和 token到期时间
            $token = IAuth::setAppLoginToken($tel);

            $data = [
                'tel' => $tel,
                'token' => $token,
                'token_expire' => strtotime('+' . config('app.login_time_out_day') . ' days'),
                'status' => 1,
                'check_status' => 10, // 认证状态 10=>占星师考核  11=>待审核  12=>考核未通过 20=>资料填写 21=>资料待审核 22=>资料审核未通过 30=>培训   40=>认证完成（可接单）
                'create_time' => $this->request->time(),
                'regiest_env' => 'APP'
            ];

            $uid = (new ZlcrAstr())->insertGetId($data);

            return show(config('code.success'), '登录成功', [
                'token' => $this->encryptWithOpenssl($token . '||' . $uid),
                'roles' => ['astrologer_not_completed'],
                'path' => '/account/index',
                'step' => User::$statusInfo[10],
                'is_consult' => 0
            ]);
        }
    }

    /**
     * @throws \Exception
     */
    public function getCode()
    {
        $tel = trim(input('tel/s', ''));
        $time = input('time/d', 0);
        $sign = trim(input('sign/s', ''));

        $headers = $this->request->header();
        if (isset($headers['app-type']) && in_array($headers['app-type'], ['ios', 'android'], true))
        {
            $tel = $this->decryptWithOpenssl($tel);
        } else if (isset($headers['app-type']) && in_array($headers['app-type'], ['flutter-web', 'flutter-mac', 'flutter-win', 'flutter-linux'], true))
        {
            if (md5($tel . $time . 'b0Rrpe5cuSONdDEz') !== $sign)
            {
                Log::write('手机号验签错误：tel=' . $tel . ',time=' . $time . 'sign=' . $sign, 'error', true);
                return show(config('code.error'), '服务异常，请稍后再试～');
            }
        }


        // 手机号是否存在
        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel))
        {
            Log::write('手机号错误：' . $tel, 'error', true);
            throw new ApiException('手机号错误', 200, 0);
        }


        $code = random_int(100000, 999999);// 六位验证码

        $alidayu = (new AppConfig())->configInfo('alidayu');

        $result = Alidayu::getInstance()->sendSms1($tel, $code, $alidayu['login_code'], 86, 'astrologer');

        if (!$result)
        {
            return show(config('code.error'), '发送失败');
        }
        $key_of_tel_code_login_error_num = 'login_error_zhunle_astrologer:' . $tel;
        Cache::rm($key_of_tel_code_login_error_num); // 登录
        $key_of_tel_code_bind_error_num = 'bind_tel_error_zhunle_astrologer:' . $tel;
        Cache::rm($key_of_tel_code_bind_error_num); // 绑定手机号

        return show(config('code.success'), '发送成功');
    }

}
